<template>
  <div class="container">
    <div class="table-wrapper" ref="tableWrapperRef">
      <!-- 根据 borderType 应用不同的类名 -->
      <table class="table" :class="`border-${borderType}`">
        <!-- 使用表头组件 -->
        <TableHeader
          :columns="columns"
          :selectable="selectable"
          :editable="editable"
          :resize="resize"
          :is-all-selected="isAllSelected"
          :is-indeterminate="isIndeterminate"
          :get-header-fixed-style="getHeaderFixedStyle"
          @select-all="handleSelectAll"
          @resize="resizeFunction"
          @action-column-resize="actionColumnResize"
        />
        <tbody>
          <tr v-for="(item, rowIndex) in data" :key="`row-${rowIndex}`">
            <td class="table__cell-index">
              <div>
                <input
                  v-if="selectable && item.isCheckbox !== false"
                  type="checkbox"
                  :checked="selectedItems.includes(rowIndex)"
                  @change="() => handleSelectRow(rowIndex)"
                />
                <input v-else-if="selectable && item.isCheckbox === false" type="checkbox" disabled />
                <span v-else>{{ rowIndex + 1 }}</span>
              </div>
            </td>
            <!-- 数据列 -->
            <td
              v-for="(column, colIndex) in columns"
              :key="column.prop"
              v-show="column.visible"
              class="table__cell"
              :class="{
                'table__fixed-column-left': column.fixed === 'left',
                'table__fixed-column-right': column.fixed === 'right'
              }"
              :style="getCellFixedStyle(column, colIndex) as any"
            >
              <!-- 编辑模式 -->
              <div v-if="column.component && editingRowIndex === rowIndex" class="table__edit-cell">
                <!-- Element Plus 输入框编辑组件 -->
                <el-input
                  v-if="column.component === 'input'"
                  v-model="editingData[rowIndex][column.prop]"
                  class="table__edit-input"
                  clearable
                  placeholder="请输入"
                  :class="{ 'is-error': validationErrors[rowIndex]?.[column.prop] }"
                  @blur="validateField(rowIndex, column.prop)"
                  @keyup.enter="saveRowEdit(rowIndex)"
                  @mouseenter="validationErrors[rowIndex]?.[column.prop] && showTooltip($event, validationErrors[rowIndex][column.prop])"
                  @mouseleave="hideTooltip"
                />

                <!-- Element Plus 下拉框编辑组件 -->
                <el-select
                  v-else-if="column.component === 'select'"
                  v-model="editingData[rowIndex][column.prop]"
                  class="table__edit-select"
                  clearable
                  placeholder="请选择"
                  :class="{ 'is-error': validationErrors[rowIndex]?.[column.prop] }"
                  @change="() => validateField(rowIndex, column.prop)"
                  @mouseenter="validationErrors[rowIndex]?.[column.prop] && showTooltip($event, validationErrors[rowIndex][column.prop])"
                  @mouseleave="hideTooltip"
                >
                  <el-option v-for="option in column.options" :key="option.value" :label="option.label || option.name" :value="option.value" />
                </el-select>
                <!-- Element Plus 日期选择器组件 -->
                <el-date-picker
                  v-else-if="column.component === 'date-picker'"
                  v-model="editingData[rowIndex][column.prop]"
                  type="date"
                  placeholder="请选择"
                  value-format="yyyy-MM-dd"
                  class="table__edit-input"
                  :class="{ 'table__edit-input--error': validationErrors[rowIndex]?.[column.prop] }"
                  @change="() => validateField(rowIndex, column.prop)"
                  @mouseenter="validationErrors[rowIndex]?.[column.prop] && showTooltip($event, validationErrors[rowIndex][column.prop])"
                  @mouseleave="hideTooltip"
                />
              </div>
              <!-- 查看模式 -->
              <div v-else v-bind="getCellContentProps(getDisplayValue(item[column.prop], column))">
                <span
                  :class="{
                    'table__cell-content': true,
                    'table__cell-dict': column.component === 'select' && column.options
                  }"
                >
                  {{ getDisplayValue(item[column.prop], column) }}</span
                >
              </div>
            </td>
            <!-- 操作列 -->
            <td v-if="editable" class="table__cell table__fixed-column-right table__action-column">
              <div class="table__action-buttons">
                <!-- 编辑状态下显示保存和取消按钮 -->
                <template v-if="editingRowIndex === rowIndex">
                  <el-button size="small" type="primary" @click="saveRowEdit(rowIndex)">保存</el-button>
                  <el-button size="small" @click="cancelRowEdit(rowIndex)">取消</el-button>
                </template>
                <!-- 非编辑状态下显示编辑和删除按钮 -->
                <template v-else>
                  <el-button size="small" type="primary" @click="startRowEdit(rowIndex)">编辑</el-button>
                  <el-button size="small" type="danger" @click="deleteRow(rowIndex)">删除</el-button>
                </template>
              </div>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <!-- 自定义Tooltip -->
    <div
      v-if="tooltip && tooltip.visible && tooltip.content && tooltip.x !== undefined && tooltip.y !== undefined"
      v-bind="getTooltipProps()"
      class="custom-tooltip"
      :class="{ 'error': isErrorTooltip }"
    >
      {{ tooltip.content }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, watch } from 'vue';
import type { Column, Cell, ValidationConfig } from './type';
import { resizeFunction, initColumnWidths, actionColumnResize, tooltipModule, fixedModule, selectedModule, editModule } from './composables/index';
import { ElInput, ElSelect, ElOption, ElDatePicker, ElButton } from 'element-plus';
import TableHeader from './header/index.vue';

const tableWrapperRef = ref<HTMLElement | null>(null);
const isErrorTooltip = ref(false);
const props = defineProps<{
  /*数据*/
  modelValue: Cell[];
  columns: Column[];
  /*控制*/
  resize?: boolean; //手动改变宽度
  selectable?: boolean; //多选
  editable?: boolean; // 编辑是否启用
  borderType?: 'full' | 'bottom'; // 边框类型
  validationRules?: ValidationConfig; //验证规则
  editing?: boolean; // 编辑状态
  manipulate?: boolean; // 是否允许操作
  sortable?: boolean; // 是否启用排序
  /*方法*/
}>();

const borderType = props.borderType || 'full';
const resize = props.resize || true;
const selectable = props.selectable || false;
const editable = props.editable || false;

const emit = defineEmits<{
  (e: 'update:modelValue', value: Cell[]): void;
  (e: 'update:columns', value: Column[]): void;
  (e: 'selection-change', selectedRows: Cell[]): void;
  (e: 'row-edit', rowIndex: number, newRowData: any): void;
  (e: 'row-delete', rowIndex: number): void;
  (e: 'edit-change', payload: { rowIndex: number; colIndex: number; newValue: any }): void;
  (e: 'update:editing', value: boolean): void;
}>();

// 创建计算属性用于双向绑定
const data = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
});

// 初始化tooltip模块
const { tooltip, showTooltip: originalShowTooltip, hideTooltip: originalHideTooltip } = tooltipModule();

// 选择模块
const { selectedItems, isAllSelected, isIndeterminate, handleSelectRow, handleSelectAll, clearSelection, selectRows } = selectedModule(
  () => props.modelValue,
  emit
);

// 使用 editModule 替换原来的编辑相关代码
const { editingRowIndex, editingData, validationErrors, isEditingRef, startRowEdit, saveRowEdit, cancelRowEdit, deleteRow, validateField } =
  editModule(props, data, emit);

// 固定列模块
const { getHeaderFixedStyle, getCellFixedStyle } = fixedModule(tableWrapperRef.value, props.columns);

const showTooltip = (event: MouseEvent, content: string) => {
  isErrorTooltip.value = true;
  // 直接设置tooltip状态
  tooltip.content = content;
  tooltip.visible = true;
  // 计算位置
  const target = event.target as HTMLElement;
  if (target) {
    const rect = target.getBoundingClientRect();
    tooltip.x = rect.left;
    tooltip.y = rect.top - 30; // 在元素上方显示
  }
};

// 重写hideTooltip方法
const hideTooltip = () => {
  isErrorTooltip.value = false;
  originalHideTooltip();
};

// 添加字典值显示处理函数
const getDisplayValue = (value: any, column: Column) => {
  // 如果是下拉框组件且有选项配置
  if (column.component === 'select' && column.options && Array.isArray(column.options)) {
    // 查找匹配的选项
    const option = column.options.find((opt) => opt.value === value);
    return option ? option.label || option.name || value : value;
  }
  // 其他情况直接返回原值
  return value;
};

//Tooltip相关v-bind
const getTooltipProps = () => ({
  class: 'custom-tooltip',
  style: {
    top: tooltip.y + 'px',
    left: tooltip.x + 'px'
  }
});

// 监听内部编辑状态变化，同步到父组件
watch(isEditingRef, (newValue) => {
  emit('update:editing', newValue);
});

// 监听外部 editing prop 变化，同步到内部状态
watch(
  () => props.editing,
  (newValue) => {
    if (newValue !== isEditingRef.value) {
      // 如果外部设置为 true 但当前没有在编辑
      if (newValue && editingRowIndex.value === null) {
        // 如果有数据则编辑第一行，否则忽略
        if (data.value.length > 0) {
          startRowEdit(0);
        }
      }
      // 如果外部设置为 false 但当前在编辑，则取消编辑
      else if (!newValue && editingRowIndex.value !== null) {
        cancelRowEdit(editingRowIndex.value);
      }
    }
  }
);

// 单元格内容相关v-bind
const getCellContentProps = (content: string) => ({
  class: 'table__cell-content',
  onMouseenter: (event: MouseEvent) => originalShowTooltip(event, content),
  onMouseleave: originalHideTooltip
});

// 组件挂载时初始化列宽
onMounted(() => {
  initColumnWidths(tableWrapperRef.value, props.columns);
});

// 暴露方法给父组件
defineExpose({
  clearSelection,
  selectRows,
  startRowEdit,
  isEditing: isEditingRef // 暴露编辑状态
});
</script>

<style scoped>
/* === 基础布局样式 === */
.table-wrapper {
  overflow-x: auto;
  position: relative;
}

.table {
  border-collapse: separate;
  border-spacing: 0;
  width: fit-content;
  table-layout: fixed;
}

/* === 表格单元格基础样式 === */
.table th,
.table td {
  text-align: center;
  white-space: nowrap;
}

/* 根据 borderType 应用不同的边框样式 */
/* 完整边框 - 优化版，避免边框过宽 */
.table.border-full th,
.table.border-full td {
  border-top: none;
  border-left: none;
  border-right: 1px solid #dee2e6;
  border-bottom: 1px solid #dee2e6;
}

/* 表格最左边的单元格需要添加左边框 */
.table.border-full th:first-child,
.table.border-full td:first-child {
  border-left: 1px solid #dee2e6;
}

/* 表格最顶部的表头需要添加顶边框 */
.table.border-full thead th {
  border-top: 1px solid #dee2e6;
}

/* 表格右下角需要添加边框 */
.table.border-full tbody tr:last-child td {
  border-bottom: 1px solid #dee2e6;
}

.table.border-full tbody tr:last-child td:last-child {
  border-right: 1px solid #dee2e6;
}

/* 仅底部边框 */
.table.border-bottom th,
.table.border-bottom td {
  border-left: none;
  border-right: none;
  border-top: none;
  border-bottom: 1px solid #dee2e6;
}

.table.border-bottom th:first-child,
.table.border-bottom td:first-child {
  border-left: 1px solid #dee2e6;
}

.table.border-bottom th:last-child,
.table.border-bottom td:last-child {
  border-right: 1px solid #dee2e6;
}

.table.border-bottom thead th {
  border-top: 1px solid #dee2e6;
}

/* 无边框 */
.table.border-none th,
.table.border-none td {
  border: none;
}

/* 仅水平边框 */
.table.border-horizontal th,
.table.border-horizontal td {
  border-left: none;
  border-right: none;
  border-top: none;
  border-bottom: 1px solid #dee2e6;
}

.table.border-horizontal thead th {
  border-top: 1px solid #dee2e6;
}

/* 仅垂直边框 */
.table.border-vertical th,
.table.border-vertical td {
  border-top: none;
  border-bottom: none;
  border-left: none;
  border-right: 1px solid #dee2e6;
}

.table.border-vertical th:last-child,
.table.border-vertical td:last-child {
  border-right: none;
}

.table.border-vertical th:first-child,
.table.border-vertical td:first-child {
  border-left: 1px solid #dee2e6;
}

.table.border-vertical thead th {
  border-top: 1px solid #dee2e6;
}

/* === 默认宽度设置 === */
.table th:not(.table__cell-index),
.table td:not(.table__cell-index) {
  min-width: 50px;
}

/* === 序号列样式 === */
/* 表头序号列 - 最高层级的固定元素 */
.table thead th.table__cell-index {
  width: 30px;
  font-weight: 600;
  position: sticky;
  top: 0;
  left: 0;
  z-index: 20;
}

/* 仅在 full 和 vertical 模式下添加右边框 */
.table.border-full thead th.table__cell-index,
.table.border-vertical thead th.table__cell-index {
  border-right: 1px solid #dee2e6;
}

/* 内容序号列 - 内容区域最高的固定列 */
.table__cell-index {
  width: 30px;
  font-weight: 600;
  position: sticky;
  left: 0;
  z-index: 18;
}

/* 仅在 full 和 vertical 模式下添加右边框 */
.table.border-full .table__cell-index,
.table.border-vertical .table__cell-index {
  border-right: 1px solid #dee2e6;
}

/* 序号列复选框样式 */
.table__cell-index input[type='checkbox'] {
  vertical-align: middle;
}

.table__cell-index input[type='checkbox']:indeterminate {
  background-color: #007bff;
}

.table__cell-index input[type='checkbox']:indeterminate::after {
  content: '';
  display: block;
  width: 10px;
  height: 2px;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* === 固定列样式 === */
/* 左侧固定列样式 */
.table__fixed-column-left {
  box-shadow: 1px 0 2px rgba(0, 0, 0, 0.1);
  border-right: 1px solid #dee2e6; /* 左侧固定列右边框 */
}

/* 右侧固定列样式 */
.table__fixed-column-right {
  box-shadow: -1px 0 2px rgba(0, 0, 0, 0.1);
  border-left: 1px solid #dee2e6; /* 右侧固定列左边框 */
}

/* 普通表头 */
.table thead th {
  position: sticky;
  top: 0;
  height: 40px;
  z-index: 10;
  user-select: none;
  background: #f0f0f0;
  color: #495057;
}

/* 应用背景色 */
.table tbody td {
  background-color: #ffffff;
}

/* 斑马纹效果 */
.table tbody tr:nth-child(even) td {
  background-color: #e8f5e8;
}

/* === 列宽调整样式 === */
.table__resizer {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 4px;
  cursor: col-resize;
  z-index: 30; /* 确保调整器在最上层 */
}

.table__resizer:hover {
  background-color: rgba(59, 138, 223, 0.92);
}

.table__header-content,
.table__cell-content {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
  cursor: default;
  font-size: 13px;
  position: relative;
  box-sizing: border-box;
  padding: 3px 5px;
}

/* === 编辑模式样式 === */
.table__edit-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  margin: 0 2px;
}

.table__edit-input,
.table__edit-select {
  width: 100%;
  height: calc(100% - 6px); /* 留出一些边距 */
  outline: none;
  box-sizing: border-box;
  margin: 3px 0; /* 垂直居中的边距 */
}

.table__edit-input:focus,
.table__edit-select:focus {
  /* 修改focus状态的边框样式 */
  border-color: #409eff;
  box-shadow: 0 0 3px rgba(64, 158, 255, 0.5);
}

/* 编辑错误状态样式 - 提高优先级 */
.table__edit-input.is-error,
.table__edit-select.is-error {
  border: 1px solid #f56c6c !important;
  box-shadow: 0 0 3px rgba(245, 108, 108, 0.5) !important;
  border-radius: 4px;
  animation: shake 0.4s ease-in-out;
}

.table__edit-input.is-error:focus,
.table__edit-select.is-error:focus {
  border: 1px solid #f56c6c !important;
  box-shadow: 0 0 5px rgba(245, 108, 108, 0.7) !important;
}

/* 抖动动画 */
@keyframes shake {
  0%,
  100% {
    transform: translateX(0);
  }
  10%,
  30%,
  50%,
  70%,
  90% {
    transform: translateX(-1px);
  }
  20%,
  40%,
  60%,
  80% {
    transform: translateX(1px);
  }
}

/* === 操作列样式 === */
.table__action-column {
  width: auto;
  min-width: 150px;
  padding: 0 5px;
  z-index: 25;
  height: 42px;
  position: sticky;
  right: 0;
  border-left: 1px solid #dee2e6; /* 操作列左边框 */
}

/* 操作按钮布局 */
.table__action-buttons {
  display: flex;
  justify-content: center;
  gap: 5px;
  align-items: center;
  white-space: nowrap;
}

/* === 字典值样式 === */
.table__cell-dict {
  background-color: #ecf5ff;
  color: #409eff;
  border-radius: 4px;
  padding: 2px 8px !important;
  font-weight: 600;
  font-size: 14px;
}

/* 暗色主题适配 */
@media (prefers-color-scheme: dark) {
  .table__cell-dict {
    background-color: #1a3c5e;
    color: #64a5ff;
  }

  /* 暗色主题下的边框颜色调整 */
  .table.border-full th,
  .table.border-full td,
  .table.border-bottom th,
  .table.border-bottom td,
  .table.border-horizontal th,
  .table.border-horizontal td,
  .table.border-vertical th,
  .table.border-vertical td {
    border-color: #444;
  }

  .table thead th.table__cell-index,
  .table__cell-index,
  .table__fixed-column-left,
  .table__fixed-column-right,
  .table__action-column {
    border-color: #444;
  }
}

/* === Tooltip样式 === */
.custom-tooltip {
  position: fixed;
  background-color: rgba(0, 0, 0, 0.75);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.custom-tooltip.error {
  background-color: #f56c6c;
}

/* 拖拽指示器样式 */
.table-resize-proxy {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background-color: #409eff;
  z-index: 9999;
  display: none;
}

/* 拖拽时的列样式 */
th.noclick,
td.noclick {
  pointer-events: none;
  user-select: none;
}

/* 拖拽时的光标样式 */
.table-wrapper.dragging {
  cursor: col-resize;
}
</style>
